#!/bin/bash

#set -x
tmp="/var/log/messages*"
[ "$tmp" != "/var/log/messages*" ] && logs="$tmp"
tmp="/var/log/syslog*" 
[ "$tmp" != "/var/log/syslog*" ] && logs="$logs $tmp"
out_file="auto_collected_log_$(date +%Y%m%d)"
debug=false
tar_exclude=""
tar_dereference=""
force=0
msg="Date: `date -R`"
cmds=""

function colorEcho {
    case "$1" in
    -g|--green)
        echo -e "\033[1;32m$2\033[0m";;
    -r|--red)
        echo -e "\033[1;31m$2\033[0m";;
    -y|--yellow)
        echo -e "\033[1;33m$2\033[0m";;
    esac
}

show_version() {
    colorEcho -g "Version: 1.0.0"
    colorEcho -g "Author: LysLee"
    colorEcho -g "Email: 2786080468@qq.com"
}

usage() {
    cat << EOF
A shell script to collect linux log.

Usage:
    $0 [Options...] 
Options:
    -a|--add <path...>: add path to output file
    -c|--cmd <cmd>: exec <cmd> and collect the output
    -d|--debug: debug
    --dereference: follow symlinks(tar opts)
    -e|--exclude '<path>': exclude <path> from tar
    -f|--force: force to collect logs even not root
    -h|--help: show this help message
    -m|--message: add message to readme of output file
    -o|--output <output_file>: output file
    -r|--remove '<path...>': remove path from output file
    -v|--verbose: show detail
    -V|--version: show version

Without any option, will only pack /var/log/messages* /var/log/syslog* and general system info

Eg:
    $0 -a /tmp/a.log -o testlog -e '/var/log/httpd' \
-e '/var/log/boo*'
    $0 -m "/etc/*: SystemVersion" -m "This is a test for log-collector" -e "/var/log/journal" -d -c 'ls /boot -lh' -c "df -hT"  -a '/etc/system-release /etc/fstab' -o testlog  --dereference
EOF
}

#Phrase options
opts=$(getopt -o "a:c:de:fhm:o:r:vV" --long  "add:,cmd:,debug,dereference,exclude:,\
force,help,message:,output:,remove:,verbose,version" -n "$0" -- "$@")
if [ $? -ne 0 ]; then
    colorEcho -r "Phrase opts error"
    usage
    exit 4
fi

eval set -- $opts


while [ -n "$1" ]; do
    case "$1" in
    -a|--add)
        logs="$logs ${2%/}"
        shift 2;;
    -c|--cmd)
        cmds="$cmds
$2"
        shift 2;;
    -d|--debug)
        debug=true
        shift;;
    --dereference)
        tar_dereference="--dereference"
        shift;;
    -e|--exclude)
        tar_exclude="$tar_exclude --exclude ${2%/}"
        shift 2;;
    -f|--force)
        force=1
        shift;;
    -h|--help)
        usage
        exit;;
    -m|--message)
        msg="$msg
$2"
        shift 2;;
    -o|--output)
        out_file=$2
        shift 2;;
    -r|--remove)
        logs="${logs/${2%/}/}"
        shift 2;;
    -v|--verbose)
        verbose='v'
        shift;;
    -V|--version)
        show_version
        exit;;
    --)
        shift
        break;;
    *)
        colorEcho -r "Unknown opt:$1"
        usage
        exit 3;;
    esac
done

#determin the user_id
if [ "$UID" -ne 0 ] && [ "$force" -eq 0 ]; then
    colorEcho -r "You'd better run the collector as root!"
    exit 1
fi
readme=/var/log/${out_file##*/}_readme
sysconfig=/var/log/${out_file##*/}_sysconfig
msg="$msg
$sysconfig: System config message"

#add readme and sysconfig
#if [[ ! "$logs" =~ (^|[[:space:]])/var/log($|[[:space:]])  ]]; then
    logs="$logs $readme  $sysconfig"
#fi

#debug
if $debug; then
    echo opts: $opts
    echo logs: $logs
    echo tar -c${verbose}zf "${out_file}.tar.bz2"  $logs $tar_exclude $tar_dereference
fi
for log in $logs; do
    if [ "$log" = "/" ]; then
        colorEcho -y 'Warning `/` is included, the collector will do nothing!'
        exit 2
    fi
done

#collect system config
#############################
#(set -x
#    lscpu
#    lsblk  -o name,size,type,mountpoint,rota
#    lspci -knn
#    free -m
#    ifconfig
#    top -n 1 -b
#    dmidecode
#    cat /proc/cpuinfo
#) >& /var/log/${out_file##*/}_sysconfig
#(echo "$cmds" |while read cmd; do
#    (set -x
#    $cmd)
#done
#)>> /var/log/${out_file##*/}_sysconfig 2>&1
###############################
cmds="lscpu
lsblk  -o name,size,type,mountpoint,rota
lspci -knn
free -m
ifconfig
top -n 1 -b
dmidecode
dmesg
cat /proc/cpuinfo
hdparm -i /dev/[sh]d[a-z]
$cmds"
echo "$cmds" |while read cmd; do
    [ -z "$cmd" ] && continue
    echo "+ $cmd"
    bash -c "$cmd"   #利用子bash解释复杂命令  
    if [ $? -ne 0 ]; then
        colorEcho  -r "exec \`$cmd\` failure!" 1>&2
    fi 
done > $sysconfig

#generate readme
echo "$msg" > $readme

tar -c${verbose}zf "${out_file}.tar.bz2"  $tar_exclude $logs  $tar_dereference
if [ $? -eq 0 ]; then
    colorEcho -g "collect logs to file $out_file.tar.bz2 finished"
    colorEcho -g "read /var/log/${out_file##*/}_readme for more info"
fi
